home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 8: LINUX Games / Linux Cubed Series 8 - LINUX Games.iso / games / x11 / strategy / connx-1.001 / connx-1~ / client.c next >
C/C++ Source or Header  |  1995-02-11  |  6KB  |  315 lines

  1. /*
  2.  * client main loop for connX
  3.  */
  4.  
  5. #include <pwd.h>
  6. #include "commun.h"
  7. #include "connect.h"
  8. #include <strings.h>
  9. #include "xconnect.h"
  10. #include <errno.h>
  11. #include <sys/types.h>
  12. #include <sys/time.h>
  13.  
  14. #ifdef AIX
  15. #include <sys/select.h>
  16. #endif
  17.  
  18. #define CHECK_RC(rc) if (rc==-1) { printf("Server exited\n"); client_exit(); }
  19.  
  20. #define NUM_FLAGS 3
  21. enum
  22.   {
  23.     F_NAME, F_DISPLAY, F_HOST
  24.   };
  25. int flags_val[] =
  26. {F_NAME, F_DISPLAY, F_HOST};
  27. char *flags_txt[] =
  28. {"-name", "-display", "-host"};
  29.  
  30. /*prototypes */
  31. void usage (char *prog);
  32. int parse_args (int argc, char **argv, char **pName, char **pDisplay_name,
  33.         char **pHost);
  34. void play_games ();
  35. void connect_to_server (char *pName);
  36. int to_flag (char *string);
  37. void client_exit ();
  38.  
  39. /*globals*/
  40. int fd;
  41. char *program_name;
  42.  
  43. /*****************************************************************************/
  44.  
  45. main (int argc, char **argv)
  46. {
  47.   int rc;
  48.   char *pDisplay_name = NULL;
  49.   char *pName = NULL;
  50.   char *pHost;
  51.   struct passwd *pInfo;
  52.   char host[80];
  53.  
  54.   if (parse_args (argc, argv, &pName, &pDisplay_name, &pHost) == -1)
  55.     {
  56.       usage (argv[0]);
  57.       exit (1);
  58.     }
  59.  
  60.   program_name = argv[0];
  61.   if (X_open (pDisplay_name) == -1)
  62.     exit (1);
  63.  
  64. #ifdef TCPIP
  65.   if (pHost == NULL)        /* use local host */
  66.     {
  67.       gethostname (host, 80);
  68.       pHost = host;
  69.     }
  70. #endif
  71.  
  72.   rc = client_open_connection (&fd, pHost);
  73.   if (rc != 0)
  74.     {
  75.       printf ("Can\'t connect\n");
  76.       exit (1);
  77.     }
  78.  
  79.   /* get default player name = userid */
  80.   if (pName == NULL)
  81.     {
  82.       pInfo = getpwuid (getuid ());
  83.       pName = pInfo->pw_name;
  84.     }
  85.   connect_to_server (pName);
  86.   play_games ();
  87. }
  88.  
  89. /****************************************************************************/
  90. /* internals ***************************************************************/
  91. /**************************************************************************/
  92.  
  93. /*
  94.  * send connection message to server
  95.  */
  96. void 
  97. connect_to_server (char *pName)
  98. {
  99.   new_player new_p;
  100.   int rc;
  101.  
  102.   strcpy (new_p.name, pName);
  103.   rc = send_message (&fd, NEW_PLAYER, sizeof (new_player), (char *) &new_p);
  104.   CHECK_RC (rc);
  105. }
  106.  
  107. /***********************************************************************/
  108.  
  109. /*
  110.  * play games of connX - exit when server exits or player selects quit
  111.  */
  112. void 
  113. play_games ()
  114.  
  115. {
  116.   gen_msg msg_recv;
  117.   game_start *start;
  118.   char data[MAX_DATA];
  119.   int my_num;
  120.   my_move mymove;
  121.   my_move *mymove_resp;
  122.   others_move *othersmove;
  123.   game_end *game_over;
  124.   int rc, num;
  125.   struct fd_set readfs;
  126.   struct timeval notimeout;
  127.   whose_move *whose;
  128.  
  129.   msg_recv.msg = (char *) &data;
  130.   notimeout.tv_sec = 0;
  131.   notimeout.tv_usec = 0;
  132.  
  133.  
  134.   while (1)
  135.  
  136.     {
  137.       FD_ZERO (&readfs);
  138.       FD_SET (fd, &readfs);
  139.  
  140.       /* handle expose, resize */
  141.       if (X_handle_events () == QUIT)
  142.     client_exit ();
  143.  
  144.       /* has to be non blocking to handle X-events */
  145.       if ((num = select (fd + 1, &readfs, NULL, NULL, ¬imeout)) < 0)
  146.     {
  147.       printf ("select error\n");
  148.       exit (1);
  149.     }
  150.  
  151.       if (num > 0)
  152.     {            /* handle incoming message */
  153.  
  154.       rc = read_message (&fd, &msg_recv);
  155.       CHECK_RC (rc);
  156.  
  157.       switch (msg_recv.msg_type)
  158.         {
  159.         case GAME_START:
  160.           start = (game_start *) msg_recv.msg;
  161.           my_num = start->your_number;
  162.           X_allocate (*start);
  163.           break;
  164.         case YOUR_MOVE:
  165.           rc = X_get_player_move (&mymove.move);
  166.           if (rc == QUIT)
  167.         client_exit ();
  168.           if (rc == FORFEIT)
  169.         {
  170.           mymove.move.row = FORFEIT;
  171.           mymove.move.column = FORFEIT;
  172.         }
  173.           rc = send_message (&fd, MY_MOVE, sizeof (mymove), (char *) &mymove);
  174.           CHECK_RC (rc);
  175.           break;
  176.         case MY_MOVE:
  177.           mymove_resp = (my_move *) msg_recv.msg;
  178.           if (mymove_resp->rc == -1)
  179.         X_bad_move ();
  180.           else
  181.         X_add_to_board (mymove_resp->move, my_num);
  182.           break;
  183.         case OTHERS_MOVE:
  184.           othersmove = (others_move *) msg_recv.msg;
  185.           if (othersmove->player_number != my_num)
  186.         X_add_to_board (othersmove->move, othersmove->player_number);
  187.           break;
  188.         case WHOSE_MOVE:
  189.           whose = (whose_move *) msg_recv.msg;
  190.           X_show_turn (whose->player);
  191.           break;
  192.         case GAME_END:
  193.           game_over = (game_end *) msg_recv.msg;
  194.           X_game_end (game_over->winner, game_over->connect[0],
  195.               game_over->connect[1]);
  196.           break;
  197.         default:
  198.           printf ("Comm problem %d\n", msg_recv.msg_type);
  199.           exit (1);
  200.         }
  201.     }
  202.     }
  203. }
  204.  
  205. /*************************************************************************/
  206.  
  207.  
  208. /* command line processing */
  209. int 
  210. parse_args (int argc, char **argv, char **pName, char **pDisplay_name,
  211.         char **pHost)
  212. {
  213.   int i;
  214.   int flag;
  215.   if (((argc - 1) % 2) != 0)
  216.     return -1;
  217.   for (i = 1; i < argc; i = i + 2)
  218.     {
  219.       flag = to_flag (argv[i]);
  220.       switch (flag)
  221.     {
  222.     case F_DISPLAY:
  223.       *pDisplay_name = argv[i + 1];
  224.       break;
  225.     case F_NAME:
  226.       *pName = argv[i + 1];
  227.       break;
  228.     case F_HOST:
  229.       *pHost = argv[i + 1];
  230.       break;
  231.     default:
  232.       return -1;
  233.     }
  234.     }
  235.  
  236.   return 0;
  237. }
  238.  
  239. /*****************************************************************************/
  240.  
  241. int 
  242. to_flag (char *string)
  243. {
  244.   int i;
  245.  
  246.   for (i = 0; i < NUM_FLAGS; i++)
  247.     if (strcmp (string, flags_txt[i]) == 0)
  248.       return flags_val[i];
  249.   return -1;
  250. }
  251.  
  252. /**************************************************************************/
  253.  
  254. void 
  255. usage (char *prog)
  256. {
  257.   int i;
  258.   printf ("Usage: %s \n", prog);
  259.   printf ("-name <player_name>\n");
  260.   printf ("-display <display>\n");
  261.   printf ("-host <host>\n\n\n");
  262. }
  263.  
  264.  
  265. /********************************************************************/
  266.  
  267. /*
  268.  * check if server cancelled move
  269.  * Note: if server cancels game, next message on queue indicates so
  270.  */
  271. int 
  272. move_cancelled ()
  273. {
  274.   int rc;
  275.   gen_msg msg_recv;
  276.   struct fd_set readfs;
  277.   struct timeval notimeout;
  278.   char data[MAX_DATA];
  279.  
  280.   msg_recv.msg = (char *) &data;
  281.   notimeout.tv_sec = 0;
  282.   notimeout.tv_usec = 0;
  283.  
  284.   FD_ZERO (&readfs);
  285.   FD_SET (fd, &readfs);
  286.  
  287.   if (select (fd + 1, &readfs, NULL, NULL, ¬imeout) > 0)
  288.     {
  289.       rc = read_message (&fd, &msg_recv);
  290.       CHECK_RC (rc);
  291.  
  292.       if (msg_recv.msg_type == CANCEL_MOVE)
  293.     /* cancelled */
  294.     return 1;
  295.     }
  296.  
  297.   /* not cancelled */
  298.   return 0;
  299.  
  300. }
  301.  
  302. /***********************************************************************/
  303.  
  304. /*
  305.  * terminate client
  306.  */
  307. void 
  308. client_exit ()
  309. {
  310.   X_deallocate ();
  311.   X_close ();
  312.   close (fd);
  313.   exit (0);
  314. }
  315.